package com.fjeld.server.store;

import static com.fjeld.middleware.activemq.BrokerEnum.*;
import com.fjeld.server.store.reader.XMLPersistanceFileReader;
import com.fjeld.server.store.reader.XMLKit;
import com.fjeld.middleware.activemq.TopicListener;
import com.fjeld.middleware.activemq.TopicPublisher;
import com.fjeld.middleware.jaxb.V1ServerRequest;
import com.fjeld.middleware.jaxb.V1ServerResponse;
import com.fjeld.middleware.jaxb.V1List;
import com.fjeld.middleware.jaxb.ObjectFactory;
import com.fjeld.middleware.cache.CacheManager;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import java.io.Serializable;
import java.lang.reflect.Method;

import org.apache.log4j.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: fjelds
 * Date: Jan 19, 2010
 * Time: 9:16:51 PM
 * <p/>
 * <p/>
 * Class containing a listener and publisher, tied to content. Maintains a map of ID to content
 * for easy retrieval.
 */
public class StorageManager extends CacheManager
{
    private static final Logger logger = Logger.getLogger(StorageManager.class);
    private ObjectFactory factory;

    /**
     * @param name - Used to identify the storage manager, used in topics.
     * @throws JMSException
     * @throws ClassNotFoundException
     */
    public StorageManager(String name) throws JMSException, ClassNotFoundException
    {
        super(ServerListenerTopicString.getValue() + "." + name,
                ServerPublisherTopicString.getValue() + "." + name,
                new XMLPersistanceFileReader(name));
        factory = new ObjectFactory();
    }

    /**
     * Should be threaded.
     *
     * @param serializable
     * @throws Exception
     */
    protected void handleMessage(Serializable serializable) throws Exception
    {
        V1ServerRequest request = (V1ServerRequest) serializable;
        logger.info("[" + topicName + "] Handling message:\n" + XMLKit.xmlObjToString(request));
        String methodName = request.getType();
        String value = request.getValue();

        Object object;
        if (value != null)
        {
            Method method = handlerInstance.getClass().getMethod(methodName, request.getClass());
            object = method.invoke(handlerInstance, request);
        } else
        {
            Method method = handlerInstance.getClass().getMethod(methodName);
            object = method.invoke(handlerInstance);
        }

        if (object != null)
        {
            V1ServerResponse response = createResponse((V1List) object, methodName);

            managerPublisher.publish(response);
            logger.info("[" + topicName + "] Published:\n" + XMLKit.xmlObjToString(response));
        } else
        {
            logger.warn("No response generated for request.");
        }
    }

    private V1ServerResponse createResponse(V1List v1List, String methodName)
    {
        V1ServerResponse response = factory.createV1ServerResponse();
        response.setType(methodName);
        response.setV1List(v1List);

        return response;
    }
}
